package com.baofu.paycore.biz.engine.processor.impl;

import com.baofu.paycore.biz.engine.command.impl.BankCommand;
import com.baofu.paycore.biz.engine.processor.BaseProcessor;
import com.baofu.paycore.biz.engine.result.CommandResult;
import com.baofu.paycore.biz.enums.CommandProcessorEnum;
import com.baofu.paycore.service.facade.enums.ServiceCodeEnum;
import com.baofu.paycore.service.facade.RechargeServiceFacade;
import com.baofu.paycore.service.facade.enums.PayStatusEnums;
import com.baofu.paycore.service.facade.enums.RequestSystemEnum;
import com.baofu.paycore.service.facade.model.FundBaseDTO;
import com.baofu.paycore.service.facade.model.recharge.RechargeDTO;
import com.baofu.paycore.service.facade.model.recharge.RechargeResDTO;
import com.system.commons.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.jboss.logging.MDC;
import org.slf4j.helpers.SystemMarker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 银行处理器
 * <p>
 *     1、获取处理器类型
 *     2、执行特定支付工具的特定支付类型的批量支付命令
 *     3、执行取消方法
 * </p>
 *
 * User: LZQ Date: 2016/04/22  Version: 1.0
 */
@Slf4j
@Service
public class BankProcessor implements BaseProcessor<BankCommand> {

    /** 充值服务 */
    @Autowired
    private RechargeServiceFacade rechargeService;

    /**
     * 获取处理器类型
     *
     * @return 命令处理器
     */
    @Override
    public CommandProcessorEnum getProcessorType() {
        return CommandProcessorEnum.BANK_PROCESSOR;
    }

    /**
     * 执行特定支付工具的特定支付类型的批量支付命令，并返回相应的结果
     *
     * @param bankCommand 支付命令
     * @return         指令执行结果
     */
    @Override
    public Map<String, CommandResult> doProcess(BankCommand bankCommand) {
        log.debug("进入银行卡类处理器：commands={}", bankCommand);
        Map<String, CommandResult> result = new HashMap<>();
        try {
            RechargeDTO rechargeDTO = convertToRechargeDTO(bankCommand);
            log.info("统一支付充值请求参数，request={}", rechargeDTO);
            Result<RechargeResDTO> rechargeResDTO =
                    rechargeService.recharge(rechargeDTO,bankCommand.getTraceLogId());

            //由于调用充值facade接口，而facade接口会商户MDC中存放的transLogId，需要再次放入
            MDC.put(SystemMarker.TRACE_LOG_ID, bankCommand.getTraceLogId());
            log.info("统一支付充值请求结果，result={}", rechargeResDTO);

            CommandResult payResult = new CommandResult();
            if (rechargeResDTO != null && rechargeResDTO.isSuccess()) {
                RechargeResDTO rechargeResult = rechargeResDTO.getResult();
                payResult.setRealRtnFlag(rechargeResult.isRealRtnFlag());
                payResult.setStatus(rechargeResult.getStatus());
                payResult.setResultCode(rechargeResult.getErrorCode());
                payResult.setResultMsg(rechargeResult.getErrorMsg());
                payResult.setResponseDate(rechargeResult.getRespDate());
                payResult.setResultVO(rechargeResult);
                payResult.setResponseNo(rechargeResult.getPayNo());
            }
            payResult.setCommand(bankCommand);
            result.put(bankCommand.getCommandNo(), payResult);
        } catch (Exception e) {
            log.error("统一支付充值指令处理失败{}", e);
            CommandResult payResult = new CommandResult();
            payResult.setStatus(PayStatusEnums.FAIL.getCode());
            payResult.setRealRtnFlag(false);
            result.put(bankCommand.getCommandNo(), payResult);
        }
        return result;
    }

    /**
     * 执行取消方法
     *
     * @param commands 支付命令
     * @return v        指令执行结果
     */
    @Override
    public Map<String, CommandResult> doCancel(List<BankCommand> commands) {
        return null;
    }

    /**
     * 银行充值
     *
     * @param bankCommand 银行类支付指令
     * @return            银行快捷请求参数
     */
    protected RechargeDTO convertToRechargeDTO(BankCommand bankCommand) {

        RechargeDTO recharge = new RechargeDTO();
        //关联号(交易号)
        recharge.setRelationNo(bankCommand.getRelationNo());
        recharge.setRequestSystem(RequestSystemEnum.PAYCORE.getCode());//区分是支付调用的充值还是其他系统调用的充值
        recharge.setRequestOrderNo(bankCommand.getRequestOrderNo());
        recharge.setRequestBizNo(bankCommand.getRequestBizNo());
        recharge.setRequestChannel(bankCommand.getRequestChannel());
        recharge.setRequestDate(bankCommand.getRequestDate());
        recharge.setCcy(bankCommand.getCcy());
        recharge.setAmt(bankCommand.getAmount());
        recharge.setServiceCode(ServiceCodeEnum.RECHARGE.getCode());
        recharge.setDescription(bankCommand.getDescription());
        recharge.setBizType(bankCommand.getBizType());
        recharge.setSubBizType(bankCommand.getSubBizType());
        recharge.setContractNo(bankCommand.getContractNo());
        recharge.setAccountNo(bankCommand.getPayeeAccNo());
        recharge.setMerchantNo(bankCommand.getMerchantNo());
        recharge.setOperator(bankCommand.getOperator());
        recharge.setPaymentExt(bankCommand.getPaymentExt());
        FundBaseDTO fundBaseDTO = new FundBaseDTO();
        fundBaseDTO.setBizChargeAmount(bankCommand.getBizChargeAmt());
        fundBaseDTO.setBizFeeAccount(bankCommand.getBizFeeAccount());
        fundBaseDTO.setPayToolType(bankCommand.getPayTool());
        fundBaseDTO.setPayToolSubType(bankCommand.getSubPayTool());
        fundBaseDTO.setAmt(bankCommand.getAmount());
        fundBaseDTO.setCcy(bankCommand.getCcy());
        fundBaseDTO.setAgreeRelId(bankCommand.getAgreeRelId());
        fundBaseDTO.setAgreementNo(bankCommand.getAgreementNo());
        fundBaseDTO.setBankCode(bankCommand.getBankCode());
        fundBaseDTO.setOpFlag(bankCommand.getOpFlag());
        if(bankCommand.getCardType() != null){
            fundBaseDTO.setCardType(bankCommand.getCardType().getCode());
        }
        recharge.setFundBaseDTO(fundBaseDTO);
        recharge.setReturnUrl(bankCommand.getReturnUrl());

        return recharge;
    }

}
